package cn.mugutu.finance.utils;

import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

/**
 * JavaBean 排序工具 根据某字段 升序降序 排序
 * @see FieldComparator
 * @author ly-suse
 * 2015年4月11日 下午12:59:23
 */
public class BeanSortUtil {
    /**
     * 降序排序
     */
    public static final int SORT_DESC = 0;
    /**
     * 升序排序
     */
    public static final int SORT_ASC = 1;

    /**
     * 排序list列表,按对象的order字段的sort(BeanSortUtil.SORT_DESC 降序,BeanSortUtil.SORT_ASC 升序)方式排序
     * @see BeanSortUtil#SORT_DESC
     * @see BeanSortUtil#SORT_ASC
     * @param list
     * @param order
     * @param sort
     */
    public static <T> void sort(List<T> list, String order, int sort) {
        if ((list == null) || (list.size() <= 0)) {
            return;
        }
        Field field = null;
        try {
            field = list.get(0).getClass().getDeclaredField(order);
            if (field == null) { return; }
            field.setAccessible(true);
            if (!TypeUtils.isNumber(field.get(list.get(0)))) {
                PrintUtil.print(order + " 属性不为数字类型");
                return;
            }
        } catch (NoSuchFieldException e) {
            PrintUtil.print(order + " 属性不存在");
            return;
        } catch (Exception e) {
            e.printStackTrace();
            PrintUtil.print("未知异常");
            return;
        }
        Collections.sort(list, new FieldComparator<T>(field, sort));
    }

    /**
     * 字段排序器
     * @author ly-suse
     * 2015年4月11日 下午1:03:07
     * @param <E>
     */
    static final class FieldComparator<E> implements Comparator<E> {
        private Field field;
        private int sort;

        /**
         * @param field 待排序字段
         * @param sort 排序方式
         */
        public FieldComparator(Field field, int sort) {
            this.field = field;
            this.sort = sort;
            this.field.setAccessible(true);
        }

        /**
         * @param order 待排序字段
         * @param sort 排序方式
         */
        public FieldComparator(String order, int sort) {
            Class<?> clazz = getSuperClassGenricType(getClass(), 0);
            if (clazz == Object.class) { return; }
            try {
                this.field = clazz.getDeclaredField(order);
                this.field.setAccessible(true);
            } catch (NoSuchFieldException e) {
                PrintUtil.print(order + " 属性不存在");
                return;
            } catch (Exception e) {
                PrintUtil.print("未知异常");
                return;
            }
            this.sort = sort;
        }

        public int compare(E o1, E o2) {
            try {
                BigDecimal d1 = new BigDecimal(this.field.get(o1).toString());
                BigDecimal d2 = new BigDecimal(this.field.get(o2).toString());
                //如果为降序排序，则表示d1>d2时返回true
                if (this.sort == SORT_DESC) {
                    return d2.compareTo(d1);
                }
                return d1.compareTo(d2);
            } catch (IllegalArgumentException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
            return 0;
        }

        @SuppressWarnings({"unchecked", "rawtypes"})
        public Class<Object> getSuperClassGenricType(Class<?> clazz, int index) {
            Type genType = clazz.getGenericSuperclass();

            if (!(genType instanceof ParameterizedType)) {
                return Object.class;
            }

            Type[] params = ((ParameterizedType) genType).getActualTypeArguments();

            if ((index >= params.length) || (index < 0)) {
                return Object.class;
            }
            if (!(params[index] instanceof Class)) {
                return Object.class;
            }
            return (Class) params[index];
        }
    }
}
